﻿using JMI_Nucleo.Classe;
using JMI_Nucleo.JMIProvider;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace JMI_Nucleo.View.Form_Base
{
    public partial class FrmBaseConsultaPaginada : Form
    {
        private DataTable dtSource;
        private DataSet ds;
        private DbDataAdapter da;
        private DataRow linha;

        private int _campoRetorno;
        private string _campoChave;
        private string _cmdSQL;
        private string _titulo;
        private string _ordena;
        private string _campoPesquisa;
        private DbConnection _conn;
        
        private int contaPagina = 0;
        private int registroMaximo = 0;
        private int numeroRegistro = 0;
        private int pagina = 0;
        // Constante tamanho da pagina, quantidade de registro por página
        private const int tamanhoPagina = 20;

        StringBuilder sbSql;
        string sqlBase;
       
        public FrmBaseConsultaPaginada()
        {
            InitializeComponent();
        }

        public string CmdSQL
        {
            get
            {
                return _cmdSQL;
            }
            set
            {
                _cmdSQL = value;
            }
        }

        public string Titulo
        {
            get
            {
                return _titulo;
            }
            set
            {
                _titulo = value;
            }
        }

        public string Ordena
        {
            get
            {
                return _ordena;
            }
            set
            {
                _ordena = value;
            }
        }

        public string CampoPesquisa
        {
            get
            {
                return _campoPesquisa;
            }
            set
            {
                _campoPesquisa = value;
            }
        }

        public DbConnection ConexaoBD
        {
            get
            {
                return _conn;
            }
            set
            {
                _conn = value;
            }
        }

        public int CampoRetorno
        {
            get
            {
                return _campoRetorno;
            }
            set
            {
                _campoRetorno = value;
            }
        }

        public string CampoChave
        {
            get
            {
                return _campoChave;
            }
            set
            {
                _campoChave = value;
            }
        }

        private  void InicializaConsulta()
        {
            sbSql = new StringBuilder();
            lblTitulo.Text = Titulo;
            sqlBase = CmdSQL;
            if (this.ActiveControl == null)
                this.SelectNextControl(cboOpcao, true, true, true, true);
            TxtPesquisa.Focus();
        }

        private bool PaginaCarregada()
        {
            if (tamanhoPagina == 0)
            {
                JMIMsg.MsgAlerta("Não foi definido o tamanho da página.");
                return false;
            }
            else
               return true;
        }

        protected void CarregaGrid()
        {
            if (dtSource == null) { return; }
            registroMaximo = dtSource.Rows.Count;
            contaPagina = registroMaximo / tamanhoPagina;

            if ((registroMaximo % tamanhoPagina) > 0)
                contaPagina++;
           
            pagina = 1;
            numeroRegistro = 0;

            // Carrega Página 
            CarregaPagina();
        }

        protected void CarregaDataSet()
        {
            try
            {
                DbProviderFactory factory = DbProviderFactories.GetFactory(ConexaoBD);

                DbCommand comando = _conn.CreateCommand();

                comando.Connection = _conn;
                comando.CommandText = CmdSQL;
 
                da = factory.CreateDataAdapter();
                da.SelectCommand = comando;

                ds = new DataSet();
                da.Fill(ds, "Items");  

                dtSource = ds.Tables["Items"];
            }
            catch (Exception e)
            {
                JMIMsg.MsgErro("Falha ao carregar dataset: " + e.Message);
            }
        }
              
        protected virtual void BotaoOK()
        {
            if (linha.ItemArray.Length > 0)
                CampoRetorno = Convert.ToInt32(linha[CampoChave]);
            Close();
        }
      
        protected virtual void BotaoFiltrar()
        {
            string filtro = String.Empty;
            sbSql.Clear();
            if (String.IsNullOrEmpty(TxtPesquisa.Text))
                CmdSQL = sqlBase;
            else
            {
                CmdSQL = sqlBase;
                sbSql.Clear();
                sbSql.AppendLine(CmdSQL);
                if (String.IsNullOrEmpty(cboOpcao.Text))
                    filtro = " WHERE " + CampoPesquisa + " LIKE '%" + TxtPesquisa.Text + "%' ";
                else
                    filtro = " WHERE " + cboOpcao.Text + " LIKE '%" + TxtPesquisa.Text + "%' ";
                sbSql.AppendLine(filtro);
                if (!String.IsNullOrEmpty(Ordena))
                    sbSql.AppendLine(Ordena);
                CmdSQL = sbSql.ToString();
            }
            CarregaDataSet();
            CarregaGrid();
        }

        private void CarregaPagina()
        {
            int i = 0;
            int registroInicial;
            int registroFinal;
            DataTable tbTemp = null;

            // Cria tabela temporária com o metodo Clone
            tbTemp = dtSource.Clone();

            if (pagina == contaPagina)
                registroFinal = registroMaximo;
            else
                registroFinal = tamanhoPagina * pagina;

            registroInicial = numeroRegistro;

            if (dtSource.Rows.Count > 0)
            {
                //for (i = registroInicial; i < registroFinal - 1; i++)
                //{
                //    tbTemp.ImportRow(dtSource.Rows[i]);
                //    numeroRegistro++;
                //}

                for (i = registroInicial; i < registroFinal; i++)
                {
                    tbTemp.ImportRow(dtSource.Rows[i]);
                    numeroRegistro++;
                }
            }

            bsConsulta.DataSource = tbTemp;
            MostraContadorPagina();
        }

        private void MostraContadorPagina()
        {
            lblPagina.Text = "Página: " + String.Format("{0:D2}", pagina) + "/ " + String.Format("{0:D2}", contaPagina);
        }

        private void FrmBaseConsultaPaginada_Load(object sender, EventArgs e)
        {
            InicializaConsulta();            
        }

        private void BtnFiltrar_Click(object sender, EventArgs e)
        {
            BotaoFiltrar();
        }

        private void BtnProximo_Click(object sender, EventArgs e)
        {
            if (!PaginaCarregada()) { return; }

            pagina++;

            if (pagina > contaPagina)
            {
                pagina = contaPagina;

                if (numeroRegistro == registroMaximo)
                {
                    JMIMsg.MsgInformacao("Você está na última página!");
                    return;
                }
            }
            CarregaPagina();
        }

        private void BtnUltimo_Click(object sender, EventArgs e)
        {
            if (!PaginaCarregada()) { return; }

            if (numeroRegistro == registroMaximo)
            {
                JMIMsg.MsgInformacao("Você está na última página!");
                return;
            }

            pagina = contaPagina;

            numeroRegistro = tamanhoPagina * (pagina - 1);

            CarregaPagina();
        }

        private void BtnPrimeiro_Click(object sender, EventArgs e)
        {
           if (!PaginaCarregada()) { return; }

           if (pagina == 1)
           {
                JMIMsg.MsgInformacao("Você está na primeira página!");
                return;
           }

           pagina = 1;
           numeroRegistro = 0;

           CarregaPagina();
        }

        private void BtnAnterior_Click(object sender, EventArgs e)
        {
            if (!PaginaCarregada()) { return; }

            // If currentPage = PageCount Then
            //    recNo = pageSize * (currentPage - 2)
            // End If

            pagina--;

            if (pagina < 1)
            {
                JMIMsg.MsgInformacao("Você está na primeira página!");
                pagina = 1;
                return;
            }
            else
               numeroRegistro = tamanhoPagina * (pagina - 1);

            CarregaPagina();
        }

        private void TxtPesquisa_TextChanged(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(TxtPesquisa.Text))
            {
                CmdSQL = sqlBase;
                CarregaDataSet();
                CarregaGrid();
            }
            else
            {
                if (String.IsNullOrEmpty(CampoPesquisa))
                    JMIMsg.MsgAlerta("Campo de pesquisa não informado.");
                else
                {
                    CmdSQL = sqlBase;
                    sbSql.Clear();
                    sbSql.AppendLine(CmdSQL);
                    string filtro = " WHERE " + CampoPesquisa + " LIKE '%" + TxtPesquisa.Text + "%' ";
                    sbSql.AppendLine(filtro);
                    if (!String.IsNullOrEmpty(Ordena))
                        sbSql.AppendLine(Ordena);
                    CmdSQL = sbSql.ToString();
                    CarregaDataSet();
                    CarregaGrid();
                }
            }
        }

        private void FrmBaseConsultaPaginada_KeyUp(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.F3: BtnOK_Click(this, new EventArgs()); break;
                case Keys.F9: BtnFiltrar_Click(this, new EventArgs()); break;
                case Keys.Escape: BtnCancelar_Click(this, new EventArgs()); break;
            }
        }

        private void BtnCancelar_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void BtnOK_Click(object sender, EventArgs e)
        {
            BotaoOK();
        }

        private void bsConsulta_CurrentItemChanged(object sender, EventArgs e)
        {
            if (bsConsulta != null)
                linha = ((DataRowView)bsConsulta.Current).Row;
        }
    }
}
